﻿package com.everydayflash.pv3d.losth {
	
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.display.StageScaleMode;
	import flash.display.StageQuality;
	import flash.display.StageAlign;
	import flash.display.StageDisplayState;
	import flash.display.Bitmap;
	import flash.events.Event;
	import flash.display.BlendMode;
	import flash.system.fscommand;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.core.geom.renderables.Vertex3D;
	import org.papervision3d.core.proto.MaterialObject3D;
	import org.papervision3d.materials.BitmapAssetMaterial;
	import org.papervision3d.materials.BitmapFileMaterial;
	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.materials.WireframeMaterial;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.render.BasicRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.Viewport3D;

	public class Roadtrip extends Sprite {
		
		[Embed(source="../../../../../assets/texture.jpg")]
		private var HighwayTexture:Class;
		private var texture:MovingBitmap;
		private var terrain:MovingBitmap;
		
		[Embed(source="../../../../../assets/lightMap.jpg")]
		private var LightMap:Class;
		
		[Embed(source="../../../../../assets/map.png")]
		private var HighwayMap:Class;
		
		[Embed(source="../../../../../assets/sky.jpg")]
		private var Sky:Class;
		private var sky:Plane;
		
		private var viewport:Viewport3D;
        private var scene:Scene3D;
        private var camera:Camera3D;
        private var renderer:BasicRenderEngine;
                
		private var plane:Plane;

		private var turns:Number = 0;
		private var heights:Number = 0;
		private var sides:Number = 0;
		private var speed:Number = 8;
		
		private var size:int = 21;

		private var verteX:Array;
		private var verteY:Array;
		
		/**
		 * Main class for the Road Trip Animation demo.
		 * 
		 * See the demo here: 
		 * http://www.everydayflash.com/blog/index.php/2008/05/16/road-trip-papervision3d/
		 * 
		 * Refer to the Downloads section to get a ZIP with the rest of the assets.
		 * 
		 * Author: Bartek Drozdz [ http://www.everydayflash.com ]
		 * 
		 */
		public function Roadtrip() {
			//stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.quality = StageQuality.LOW;
			
			texture = new MovingBitmap((new HighwayTexture() as Bitmap).bitmapData, (new LightMap() as Bitmap).bitmapData);
			terrain = new MovingBitmap((new HighwayMap() as Bitmap).bitmapData);

			initPapervision3D();
			buildPlane();

			stage.addEventListener(KeyboardEvent.KEY_UP, toggleFs);
			addEventListener(Event.ENTER_FRAME, render);
		}
		
		private function toggleFs(ke:KeyboardEvent):void {
			if (ke.keyCode == Keyboard.SPACE) {
				stage.displayState = StageDisplayState.FULL_SCREEN;
			}
		}
		
        private function initPapervision3D():void{
            viewport = new Viewport3D(520, 300);
			addChild(viewport);
            scene = new Scene3D();
            camera = new Camera3D();
            camera.zoom = 16;
            renderer = new BasicRenderEngine();
		}
		
		private function buildPlane():void {
			var skyMat:BitmapMaterial = new BitmapMaterial((new Sky() as Bitmap).bitmapData);
			skyMat.smooth = true;
			sky = new Plane(skyMat, 560, 140, 1, 1);
			sky.z = 500;
			sky.y = 100;
			scene.addChild(sky);
			
			plane = new Plane(null, 400, 1200, size-1, size-1);
			plane.y = -10;
			plane.z = -320;
			plane.material = new BitmapMaterial(texture.getSnapshot());
			plane.rotationX = -89;
			scene.addChild(plane);
			
			var vs:Array = plane.geometry.vertices;
			var vc:int = vs.length;
			
			verteX = new Array();
			verteY = new Array();
			
			for (var i:int = 0; i < vc; i++) {
				var v:Vertex3D = vs[i] as Vertex3D;
				verteX.push(v.x);
				verteY.push(v.y);
			}
		}
		
		private function render(e:Event):void {
			texture.move(speed);
			terrain.move(speed * -.33);
			
			var vs:Array = plane.geometry.vertices;
			var vc:int = vs.length;
			var terrainSnapshot:BitmapData = terrain.getSnapshot(.2);
			
			for (var i:int = 0; i < vc; i++) {
				var px:int = i % size;
				var py:int = i / size;
				var v:Vertex3D = vs[i] as Vertex3D;
				var vzpos:Number = terrainSnapshot.getPixel(py, px) & 0xff;
				v.z = vzpos * (Math.sin(sides) + 1) * -0.2;
				v.x = verteX[i] + px * Math.sin(turns) * Math.cos(px / 5) * 3;
				v.z += px * Math.cos(heights) * Math.cos(px / 5) * 1.2;
			}

			turns += 0.02;
			heights += 0.015;
			sides += 0.01;
			
			BitmapMaterial(plane.material).updateBitmap();
			
            renderer.renderScene(scene, camera, viewport);
        }
		
		public static function xtrace(msg:Object):void {
			fscommand("trace", msg.toString());
		}
	}
}